package shared

import java.io.File
import monocle.macros.Lenses
import shared.pojo.WorkflowMission.{FsData}
import shared.tool.DefaultPickle
import upickle.default._

/** Created by yz on 18/8/2020
  */
object Pojo {

  trait SoftT {
    val nameStr: String
    lazy val messageName: String = nameStr
    val videoFileName: String = ""
  }

  trait SubSoftT {
    val nameStr: String
  }

  trait NaIdentifySoftT extends SubSoftT {
    override val nameStr: String = "naIdentify"
  }

  trait RemoveQcT extends SubSoftT {
    override val nameStr: String = "removeQc"
  }

  trait ColRemoveSoftT extends SubSoftT {
    override val nameStr: String = "colRemove"
  }

  trait RowRemoveSoftT extends SubSoftT {
    override val nameStr: String = "rowRemove"
  }

  trait QcFilterSoftT extends SubSoftT {
    override val nameStr: String = "qcFilter"
  }

  trait VarMergeSoftT extends SubSoftT {
    override val nameStr: String = "varMerge"
  }

  trait NaFillSoftT extends SubSoftT {
    override val nameStr: String = "naFill"
  }

  trait NormalSoftT extends SubSoftT {
    override val nameStr: String = "normal"
  }

  trait LoessSoftT extends SubSoftT {
    override val nameStr: String = "loess"
  }

  trait TransformSoftT extends SubSoftT {
    override val nameStr: String = "transform"
  }

  trait InnerNormalSoftT extends SubSoftT {
    override val nameStr: String = "innerNormal"
  }

  trait ExtraNormalSoftT extends SubSoftT {
    override val nameStr: String = "extraNormal"
  }

  trait LevelRemoveRowSoftT extends SubSoftT {
    override val nameStr: String = "levelRemoveRow"
  }

  trait StandardSoftT extends SubSoftT {
    override val nameStr: String = "standard"
  }

  trait AnnoSoftT extends SoftT {
    val nameStr = "anno"
    override val videoFileName: String = "17.Metabolites Class Summary"
  }

  trait PcaSoftT extends SoftT {
    val nameStr = "pca"
    override val videoFileName: String = "18.PCA"
  }

  trait VennSoftT extends SoftT {
    val nameStr = "venn"
    override val videoFileName: String = "14.Venn Plot"
  }

  trait DiffAnaSoftT extends SoftT {
    val nameStr = "diffAna"
    override val videoFileName: String = "24.Univariate Analysis -Two Groups"
  }

  trait LefseAnaSoftT extends SoftT {
    val nameStr = "lefseAna"
  }

  trait LimmaAnaSoftT extends SoftT {
    val nameStr = "limmaAna"
  }

  trait StampSoftT extends SoftT {
    val nameStr = "stamp"
  }

  trait HorizontalBoxplotSoftT extends SoftT {
    val nameStr = "horizontalBoxplot"
  }

  trait UniAnaSoftT extends SoftT {
    val nameStr = "uniAna"
  }

  trait PathwayAnaSoftT extends SoftT {
    val nameStr = "pathwayAna"
  }

  trait DiagnoseAnaSoftT extends SoftT {
    val nameStr = "diagnoseAna"
  }

  trait DiffAnaMulSoftT extends SoftT {
    val nameStr = "diffAnaMul"
    override val videoFileName: String = "23.Univariate Analysis -Multi Groups"
  }

  trait CcaRdaSoftT extends SoftT {
    val nameStr = "ccaRda"
    override val videoFileName: String = "22.CCA_RDA"
  }

  trait PreprocessSoftT extends SoftT {
    val nameStr = "preprocess"
    override val videoFileName: String = "2.Cleaning and Processing"
  }

  trait HeatmapSoftT extends SoftT {
    val nameStr = "heatmap"
    override val videoFileName: String = "21.Heatmap"
  }

  trait PlsdaSoftT extends SoftT {
    val nameStr = "plsda"
    override val videoFileName: String = "20.PLS-DA"
  }

  trait PreDealSoftT extends SoftT {
    val nameStr = "preDeal"
    override val videoFileName: String = "1.Impute Missing Values and Normalize data"
  }

  trait OplsdaSoftT extends SoftT {
    val nameStr = "oplsda"
    override val videoFileName: String = "19.OPLS-DA"
  }

  trait InterSectSoftT extends SoftT {
    val nameStr = "intersect"
  }

  trait UnionSoftT extends SoftT {
    val nameStr = "union"
  }

  trait BasicSoftT extends SoftT {
    val nameStr = "basic"
    override val videoFileName: String = "16.Metabolites Class Summary by Group"
  }

  trait BoxplotSoftT extends SoftT {
    val nameStr = "boxplot"
    override val videoFileName: String = "13.Box Plot"
  }

  trait ViolinPlotSoftT extends SoftT {
    val nameStr = "violinPlot"
    override val videoFileName: String = "12.Violin Plot"
  }

  trait BiomarkerSoftT extends SoftT {
    val nameStr = "biomarker"
  }

  trait KeggEnrichSoftT extends SoftT {
    val nameStr = "keggEnrich"
    override val videoFileName: String = "11.KEGG Pathway Analysis"
  }

  trait IPathSoftT extends SoftT {
    val nameStr = "iPath"
    override val videoFileName: String = "10.IPATH Analysis"
  }

  trait EnrichSoftT extends SoftT {
    val nameStr = "enrich"
    override val videoFileName: String = "9.Metabolite Set Enrichment Analysis"
  }

  trait CorSoftT extends SoftT {
    val nameStr = "cor"
  }

  trait ParCorSoftT extends SoftT {
    val nameStr = "parCor"
    override val videoFileName: String = "8.Correlation & Partial Correlation"
  }

  trait MetMicCorSoftT extends SoftT {
    val nameStr = "metMicCor"
    override val videoFileName: String = "7.GRaMM Correlation Analysis"
  }

  trait DiagnoseSoftT extends SoftT {
    val nameStr = "diagnose"
    override val videoFileName: String = "6.Predictive Model ROC"
  }

  trait RfSoftT extends SoftT {
    val nameStr = "rf"
    override val videoFileName: String = "5.Random Forest Feature Selection"
  }

  trait SvmSoftT extends SoftT {
    val nameStr = "svm"
    override val videoFileName: String = "4.SVM Feature Selection"
  }

  trait BorutaSoftT extends SoftT {
    val nameStr = "boruta"
    override val videoFileName: String = "3.Boruta Analysis"
  }

  trait ZScoreSoftT extends SoftT {
    val nameStr = "zScore"
    override val videoFileName: String = "15.Z-Score Scaled by Row"
  }

  trait DataPreprocessWorkflowT extends SoftT {
    val nameStr = "dataPreprocess"
  }

  trait FeatureSelectionWorkflowT extends SoftT {
    val nameStr = "featureSelection"
  }

  trait DataKind {
    val name: String
    val showDirName: String
  }

  object VarInfoDataKind extends DataKind {
    val name = "varInfo"
    val defaultFileName = "var_info.txt"
    val showDirName = "var_info"
  }

  object BiomDataKind extends DataKind {
    val name = "biom"
    val defaultFileName = "otu_table.biom"
    val showDirName = "biom"
  }

  object MetDataKind extends DataKind {
    val name = "metData"
    val defaultFileName = "met_data.txt"
    val showDirName = "met_data"
  }

  object GroupDataKind extends DataKind {
    val name = "group"
    val defaultFileName = "group.txt"
    val showDirName = "group"
  }

  trait MyRPlot {
    val name: String
  }

  trait RPlot {
    val name: String
    lazy val configFileName = s"${name}_plot_config.txt"
    lazy val configJsonFileName = s"${name}_plot_config.json"
  }

  trait PcaBoxplotT extends MyRPlot {
    val name = "pcaBoxplot"

  }

  trait ClassCountPieT extends RPlot {
    val name = "classCountPie"
  }

  trait ZScoreHeatmapT extends MyRPlot {
    val name = "zScoreHeatmap"
  }

  trait HeatmapT extends MyRPlot {
    val name = "heatmap"
  }

  trait Pca3DT extends MyRPlot {
    val name = "pca3D"
  }

  trait Plsda3DT extends MyRPlot {
    val name = "plsda3D"
  }

  trait PathwayBubbleT extends MyRPlot {
    val name = "pathwayBubble"
  }

  trait PathwayBarT extends MyRPlot {
    val name = "pathwayBar"
  }

  trait EnrichBarT extends MyRPlot {
    val name = "enrichBar"
  }

  trait RocT extends MyRPlot {
    val name = "roc"
  }

  trait RocCvT extends RPlot {
    val name = "rocCv"
  }

  trait RocCvEachT extends RPlot {
    val name = "rocCvEach"
  }

  trait PrT extends MyRPlot {
    val name = "pr"
  }

  trait RfPlotT extends RPlot {
    val name = "rfPlot"
  }

  trait SvmPlotT extends RPlot {
    val name = "svmPlot"
  }

  trait BorutaBoxT extends RPlot {
    val name = "borutaBox"
  }

  trait CorNetworkT extends RPlot {
    val name = "corNetwork"
  }

  trait EnrichNetworkT extends MyRPlot {
    val name = "enrichNetwork"
  }

  trait CorHeatmapT extends RPlot {
    val name = "corHeatmap"
  }

  trait StatPieT extends RPlot {
    val name = "statPie"
  }

  trait PlsdaBoxplotT extends MyRPlot {
    val name = "plsdaBoxplot"
  }

  trait GroupBarT extends RPlot {
    val name = "groupBar"
  }

  trait SampleBarT extends RPlot {
    val name = "sampleBar"
  }

  trait VarianceT extends MyRPlot {
    val name = "variance"
  }

  trait VPlotT extends MyRPlot {
    val name = "vPlot"
  }

  trait PermuteResultT extends MyRPlot {
    val name = "permuteResult"
  }

  trait ModelArgT extends MyRPlot {
    val name = "modelArg"
  }

  trait Oplsda2DT extends MyRPlot {
    val name = "oplsda2D"
  }

  trait Plsda2DT extends MyRPlot {
    val name = "plsda2D"
  }

  trait ZScoreT extends MyRPlot {
    val name = "zScore"
  }

  trait VolcanoT extends RPlot {
    val name = "volcano"
  }

  trait VolcanoPlotT extends MyRPlot {
    val name = "volcano"
  }

  trait CorHeatmapPlotT extends MyRPlot {
    val name = "corHeatmap"
  }

  trait BoxPlotT extends MyRPlot {
    val name = "box"
  }

  trait ViolinPlotT extends MyRPlot {
    val name = "violin"
  }

  trait StampPlotT extends MyRPlot {
    val name = "stamp"
  }

  trait HorizontalBoxplotT extends MyRPlot {
    val name = "horizontalBoxplot"
  }

  trait LdaT extends RPlot {
    val name = "lda"
  }

  trait CladogramT extends RPlot {
    val name = "cladogram"
  }

  trait FeaturesT extends RPlot {
    val name = "features"
  }

  trait Pca2DT extends MyRPlot {
    val name = "pca2D"
  }

  trait CcaRdaT extends RPlot {
    val name = "ccaRda"
  }

  trait VennT extends MyRPlot {
    val name = "venn"
  }

  trait FsVennT extends MyRPlot {
    val name = "fsVenn"
  }

  trait ArgTool

  case class TrainData(useTrain: Boolean = false, trainPercent: String = "70", seed: String = "1234")

  object TrainData {
    implicit val rw = macroRW[TrainData]
    implicit val defaultRw = DefaultPickle.macroRW[TrainData]
  }

  case class EachPreprocessData(
      kind: String = "",
      naColor: String = "#FF0000",
      colNaRate: String = "50",
      rowNaRate: String = "20",
      rsd: String = "30",
      mergeMethod: String = "sum",
      replaceMethod: String = "knn",
      knn: String = "5",
      min: String = "10",
      normalMethod: String = "sum",
      area: String = "10000",
      transformMethod: String = "log2",
      glogMethod: String = "min",
      glog: String = "1",
      rowName: String = "",
      multiple: String = "10000",
      extraColumn: String = "",
      extraMultiple: String = "10000",
      accordKind: String = "all",
      calculateMethod: String = "median",
      keepMethod: String = "more",
      constant: String = "0",
      topN: String = "10",
      topPercent: String = "10",
      standardMethod: String = "scale",
      removeGroups: List[String] = List("QC")
  )

  object EachPreprocessData {
    implicit val rw = macroRW[EachPreprocessData]
    implicit val defaultRw = DefaultPickle.macroRW[EachPreprocessData]
  }

  case class FsPreprocessData(
      datas: List[EachPreprocessData] = List.empty,
      useTrain: Boolean = false,
      trainPercent: String = "70",
      seed: String = "1234",
      nodeId: String = "preprocess_0"
  )

  object FsPreprocessData {
    implicit val rw = macroRW[FsPreprocessData]
    implicit val defaultRw = DefaultPickle.macroRW[FsPreprocessData]
  }
  case class DataMatrixData(
      groups: List[String] = List.empty,
      species1: String = "Mammals",
      species: String = "hsa",
      isSmp: String = "kegg",
      nodeId: String = "dataFileNode"
  )

  object DataMatrixData {
    implicit val rw = macroRW[DataMatrixData]
    implicit val defaultRw = DefaultPickle.macroRW[DataMatrixData]
  }
  trait AnalysisArg {}

  case class PreprocessSoftData(
      missionName: String = "",
      file: String = "",
      hasGroup: Boolean = false,
      groupFile: String = "",
      datas: List[EachPreprocessData] = List.empty,
      useTrain: Boolean = false,
      trainPercent: String = "70",
      seed: String = "1234",
      kind: String = "preprocess",
      scaleMethod: String = "scale"
  ) extends AnalysisArg

  object PreprocessSoftData {
    implicit val rw = macroRW[PreprocessSoftData]
    implicit val defaultRw = DefaultPickle.macroRW[PreprocessSoftData]
  }

  val emptyList = List.empty

  trait SharedParCorDataT {
    val missionName: String
    val file: String
    val hasExtraDataFile: Boolean
    val extraFile: String
    val hasConfounderFile: Boolean
    val confounderFile: String
    val corMethod: String
    val fdrMethod: String
    val coe: String
    val p: String
    val fdr: String
  }

  case class SharedParCorData(
      missionName: String,
      file: String,
      hasExtraDataFile: Boolean,
      extraFile: String,
      hasConfounderFile: Boolean,
      confounderFile: String,
      corMethod: String,
      fdrMethod: String,
      coe: String,
      p: String,
      fdr: String
  ) extends SharedParCorDataT

  object SharedParCorData {

    implicit val rw = macroRW[SharedParCorData]

  }

  trait SharedRfDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val ntree: String
    val hasMtry: Boolean
    val mtry: String
    val replace: String
    val hasNodesize: Boolean
    val nodesize: String
    val hasMaxnodes: Boolean
    val maxnodes: String
    val topM: String
  }

  case class SharedRfData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String,
      ntree: String,
      hasMtry: Boolean,
      mtry: String,
      replace: String,
      hasNodesize: Boolean,
      nodesize: String,
      hasMaxnodes: Boolean,
      maxnodes: String,
      topM: String
  ) extends SharedRfDataT

  object SharedRfData {
    implicit val rw = macroRW[SharedRfData]
  }

  trait DiagnoseDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val group: String
    val method: String
  }

  trait OplsdaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val group: String
    val vip: String
    val q2Y: String
    val q2YB: String
  }

  trait SharedBasicDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val isPaired: Option[String]
    val method: String
    val fcMethod: String
    val mulMethod: String
  }

  case class SharedBasicData(
      missionName: String,
      file: String,
      groupFile: String,
      isPaired: Option[String],
      method: String,
      fcMethod: String,
      mulMethod: String
  ) extends SharedBasicDataT

  object SharedBasicData {

    implicit val rw = macroRW[SharedBasicData]

  }

  trait SharedHeatmapDataT {
    val missionName: String
    val file: String
    val hasRowGroup: Boolean
    val rowGroupFile: String
    val selectColumns: List[String]
    val hasColGroup: Boolean
    val colGroupFile: String
  }

  case class SharedHeatmapData(
      missionName: String,
      file: String,
      hasRowGroup: Boolean,
      rowGroupFile: String,
      selectColumns: List[String],
      hasColGroup: Boolean,
      colGroupFile: String
  ) extends SharedHeatmapDataT

  object SharedHeatmapData {

    implicit val rw = macroRW[SharedHeatmapData]

  }

  trait PlsdaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val isPaired: Boolean
  }

  trait SharedEnrichDataT {
    val missionName: String
    val file: String
    val libType: String
  }

  case class SharedEnrichData(missionName: String, file: String, libType: String) extends SharedEnrichDataT

  object SharedEnrichData {

    implicit val rw = macroRW[SharedEnrichData]

  }

  trait SharedIPathDataT {
    val missionName: String
    val file: String
    val hasGroup: Option[String]
    val groupFile: String
    val fcMethod: String
  }

  case class SharedIPathData(
      missionName: String,
      file: String,
      hasGroup: Option[String],
      groupFile: String,
      fcMethod: String
  ) extends SharedIPathDataT

  object SharedIPathData {

    implicit val rw = macroRW[SharedIPathData]

  }

  trait SharedKeggEnrichDataT {
    val missionName: String
    val file: String
    val hasGroup: Option[String]
    val groupFile: String
    val fcMethod: String
    val method: String
    val nodeImp: String
    val species: String
    val isSmp: String
  }

  case class SharedKeggEnrichData(
      missionName: String,
      file: String,
      hasGroup: Option[String],
      groupFile: String,
      fcMethod: String,
      method: String,
      nodeImp: String,
      species: String,
      isSmp: String
  ) extends SharedKeggEnrichDataT

  object SharedKeggEnrichData {
    implicit val rw = macroRW[SharedKeggEnrichData]
  }

  trait SharedAnnoDataT {
    val missionName: String
    val file: String
  }

  case class SharedAnnoData(missionName: String, file: String) extends SharedAnnoDataT

  object SharedAnnoData {

    implicit val rw = macroRW[SharedAnnoData]

  }

  trait SharedZScoreDataT {
    val missionName: String
    val file: String
  }

  case class SharedZScoreData(missionName: String, file: String) extends SharedZScoreDataT

  trait SharedPcaDataT {
    val missionName: String
    val file: String
    val hasGroup: Boolean
    val groupFile: String
    val scaleMethod: String
    val isPaired: Boolean
  }

  case class SharedPcaData(
      missionName: String,
      file: String,
      hasGroup: Boolean,
      groupFile: String,
      scaleMethod: String,
      isPaired: Boolean
  ) extends SharedPcaDataT

  object SharedPcaData {
    implicit val rw = macroRW[SharedPcaData]
  }

  trait SharedDiffAnaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val group: String
    val isPaired: Boolean
    val method: String
    val fcMethod: String
    val pValue: String
    val useFdr: Boolean
    val fdr: String
    val log2FC: String
  }

  case class SharedDiffAnaData(
      missionName: String,
      file: String,
      groupFile: String,
      group: String,
      isPaired: Boolean,
      method: String,
      fcMethod: String,
      pValue: String,
      useFdr: Boolean,
      fdr: String,
      log2FC: String
  ) extends SharedDiffAnaDataT

  object SharedDiffAnaData {

    implicit val rw = macroRW[SharedDiffAnaData]

  }

  trait SharedLefseAnaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val level: String
    val a: String
    val w: String
    val l: String
    val y: String
  }

  case class SharedLefseAnaData(
      missionName: String,
      file: String,
      groupFile: String,
      level: String,
      a: String,
      w: String,
      l: String,
      y: String
  ) extends SharedLefseAnaDataT

  object SharedLefseAnaData {
    implicit val rw = macroRW[SharedLefseAnaData]
  }

  trait SharedLimmaAnaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val groups: List[String]
    val covs: List[String]
    val kinds: List[String]
    val fillMethod: String
    val knn: String
  }

  case class SharedLimmaAnaData(
      missionName: String,
      file: String,
      groupFile: String,
      groups: List[String],
      covs: List[String],
      kinds: List[String],
      fillMethod: String,
      knn: String
  ) extends SharedLimmaAnaDataT

  object SharedLimmaAnaData {
    implicit val rw = macroRW[SharedLimmaAnaData]
  }

  trait SharedBorutaDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val maxRuns: String
    val pValue: String
  }

  case class SharedBorutaData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String,
      maxRuns: String,
      pValue: String
  ) extends SharedBorutaDataT

  object SharedBorutaData {

    implicit val rw = macroRW[SharedBorutaData]

  }

  trait SharedSvmDataT {
    val missionName: String
    val file: String
    val groupFile: String
    val scaleMethod: String
    val kernel: String
    val cost: String
    val tolerance: String
    val epsilon: String
    val gamma: String
    val coef0: String
    val degree: String
    val topM: String
  }

  case class SharedSvmData(
      missionName: String,
      file: String,
      groupFile: String,
      scaleMethod: String,
      kernel: String,
      cost: String,
      tolerance: String,
      epsilon: String,
      gamma: String,
      coef0: String,
      degree: String,
      topM: String
  ) extends SharedSvmDataT

  object SharedSvmData {
    implicit val rw = macroRW[SharedSvmData]
  }

  case class SharedPreDealData(
      missionName: String,
      file: String,
      coef: String,
      replaceMethod: String,
      knn: String,
      min: String,
      isNormal: String
  )

  object SharedPreDealData {
    implicit val rw = macroRW[SharedPreDealData]
  }

  case class AllColorPlotData(
      colors: List[String] = List[String](),
      up: String = "#ff0000",
      down: String = "#0000ff",
      none: String = "#bebebe",
      r2xColor: String = "#ADD8E6",
      r2yColor: String = "#FFE4E1",
      q2Color: String = "#E6E6FA",
      q2yColor: String = "#0000FF",
      colorsStr: String = List("#1E90FF", "#FFFFFF", "#E41A1C").mkString(":"),
      customColors: List[String] = List("#1E90FF", "#FFFFFF", "#E41A1C"),
      naColor: String = "#DDDDDD",
      shadow: String = "#0000FF",
      rejected: String = "#FF0000",
      tentative: String = "#FFFF00",
      confirmed: String = "#00FF00",
      gradientNum: String = "30",
      borderColor: String = "#ffffff",
      annoRowColors: String = "",
      annoColColors: String = "",
      envNameColor: String = "#E41A1C",
      envLineColor: String = "#E41A1C",
      speciesColor: String = "#FF8C00"
  )

  object AllColorPlotData {
    implicit val rw = macroRW[AllColorPlotData]
    implicit val defaultRw = DefaultPickle.macroRW[AllColorPlotData]
  }

  case class AllFontPlotData(
      fontFamily: String = "Times",
      showRowName: String = "T",
      showColName: String = "T",
      xRotate: String = "90",
      yRotate: String = "0",
      rowTreeHeight: String = "50",
      colTreeHeight: String = "50",
      showNumber: String = "F",
      cellFont: String = "6",
      sampleFont: String = "7",
      envFont: String = "7",
      speciesFont: String = "7",
      claalpha: String = "0.2",
      clapew: String = "0.25",
      clascw: String = "2",
      clapcw: String = "0.75",
      clalfs: String = "6",
      claclfs: String = "8",
      feacfs: String = "13"
  )

  object AllFontPlotData {
    implicit val rw = macroRW[AllFontPlotData]
    implicit val defaultRw = DefaultPickle.macroRW[AllFontPlotData]
  }

  case class CorNetworkData(
      node1Shape: String = "ellipse",
      node1Color: String = "#555555",
      node1Alpha: String = "1",
      nodeSizeRange: String = "10,20",
      edgeWidthRange: String = "1,8",
      showNode1Label: Boolean = true,
      node1Font: String = "12",
      node1LabelColor: String = "#ffffff",
      lineAlpha: String = "0.6",
      node2Shape: String = "diamond",
      node2Color: String = "#5da5fb",
      node2Alpha: String = "1",
      showNode2Label: Boolean = true,
      node2Font: String = "12",
      node2LabelColor: String = "#ffffff"
  )

  object CorNetworkData {
    implicit val rw = macroRW[CorNetworkData]
    implicit val defaultRw = DefaultPickle.macroRW[CorNetworkData]
  }

  case class AllLayoutPlotData(
      width: String = "5",
      height: String = "4",
      colClusterMethod: String = "complete",
      showPart: String = "full",
      splitNum: String = "1",
      colSplitNum: String = "1",
      convMethod: String = "none",
      normal: String = "row",
      log: String = "lg2",
      hasBorder: String = "white",
      ox: String = "0",
      oy: String = "0",
      pointSize: String = "4",
      showEnv: String = "F",
      showSpecies: String = "F",
      speciesPointSize: String = "4",
      rocShowLegend: String = "F",
      resorientation: String = "h",
      resnscl: String = "1",
      resmfl: String = "60",
      clasc: String = "",
      claevl: String = "1",
      claml: String = "6",
      claclv: String = "1",
      clacs: String = "1.5",
      clarsl: String = "1",
      clalstartl: String = "2",
      clalstopl: String = "5",
      claastartl: String = "3",
      claastopl: String = "5",
      claminps: String = "1",
      clamaxps: String = "6",
      clarsp: String = "0.15",
      feaf: String = "diff",
      feasmean: String = "y",
      feasmedian: String = "y",
      feaca: String = "0",
      feabot: String = "0",
      featop: String = "-1",
      feafname: String = ""
  )

  object AllLayoutPlotData {
    implicit val rw = macroRW[AllLayoutPlotData]
    implicit val defaultRw = DefaultPickle.macroRW[AllLayoutPlotData]
  }

  trait SForm

  case class AllPlotData(
      x: String = "1",
      y: String = "2",
      z: String = "3",
      showSample: String = "F",
      showEllipse: String = "T",
      xFont: String = "9",
      xTitleFont: String = "12",
      yFont: String = "9",
      yTitleFont: String = "11",
      mainTitle: String = "",
      mainTitleFont: String = "8",
      legendFont: String = "8",
      legendTitle: String = "",
      legendTitleFont: String = "11",
      rowCluster: String = "F",
      rowClusterMethod: String = "complete",
      colCluster: String = "F",
      layout: AllLayoutPlotData = AllLayoutPlotData(),
      color: AllColorPlotData = AllColorPlotData(),
      font: AllFontPlotData = AllFontPlotData(),
      corNetwork: CorNetworkData = CorNetworkData()
  ) extends SForm

  object AllPlotData {

    implicit val rw = macroRW[AllPlotData]
    implicit val defaultRw = DefaultPickle.macroRW[AllPlotData]
  }

  case class IsFilterData(isFilter: Boolean = true) extends SForm

  object IsFilterData {
    implicit val rw = macroRW[IsFilterData]
  }

}
